﻿///
/// Test script file NetworkParseTest.fsx.
/// Test for NetworkParse.fs
///

#load "Network.fs"
#load "NetlistParse.fs"

open System.Text.RegularExpressions

open PathFinder.NetlistParse

(* Test for rough function *)(*
printfn "------------------------------"
printfn "Beginning Regex design test..."
printfn "------------------------------"
printfn "%s" NodeDeclarationRegex
printfn "%s" ConnectionDeclarationRegex
printfn "Reading file..."
(* Beginning of the procedure *)
let mutable recgNodes: RecognizedNode list = [] (* Out *)
let mutable recgConnections: RecognizedConnection list = [] (* Out *)
let mutable correct = true
let mutable logs: ParserLogEntry list = [] (* FOR LOGGING *)
let mutable errs: FileError list = [] (* FOR ERRORS *)
let filepath = "C:/Data/VSProjects/RouteSharp/PathFinder/netfile.txt"
let filelines = GetFileLines (filepath)
let mutable line_index = 0 (* Index for line *)
let mutable token_index = 0 (* Index for token in line *)
for i in filelines do
    line_index <- (line_index + 1)
    token_index <- 0
    let subs = i.Split ([|SeparatorChar|], System.StringSplitOptions.RemoveEmptyEntries)
    let empty = (i = "")
    printfn "line %d ==> %s [empty: %b]" line_index i empty
    for j in subs do
        token_index <- (token_index + 1)
        printfn "      token %d ==> %s" token_index j
        let rxnode = new Regex (NodeDeclarationRegex) (* Important *)
        let rxconn = new Regex (ConnectionDeclarationRegex) (* Important *)
        let rxcomm = new Regex (CommentRegex) (* Important *)
        let rxnodeid = new Regex (NodeIdentifierRegex)
        let rxweight = new Regex (WeightValueRegex)
        let n = (rxnode.Matches (j)).Count (* Important *)
        let c = (rxconn.Matches (j)).Count (* Important *)
        let m = (rxcomm.Matches (j)).Count (* Important *)
        let isnode = (n = 1) (* PARSING IMPORTANT *)
        let isconn = (c = 1) (* PARSING IMPORTANT *)
        let iscomm = (m = 1) (* PARSING IMPORTANT *)
        if ((not isnode) && (not isconn) && (not iscomm)) then
            printfn "            ***ERROR*** node: %b, conn: %b, comm: %b" isnode isconn iscomm
        let x = (rxnodeid.Matches (j)).Count
        let w = (rxweight.Matches (j)).Count
        printfn "            Node Decl: %d | Conn Decl: %d | Comment: %d | NodeId: %d | Weight: %d" n c m x w
        match (isnode, isconn, iscomm) with
            | (true, false, false) -> 
                (* Parsing a Node *)
                printfn "            ***NODE***"
                logs <- logs @ [{LineNumber = line_index; TokenNumber = token_index; Line = i; Token = j; Log = "Node recognized"}]
                let nodeid = (((((new Regex (NodeIdentifierRegex)).Match (j)).Value).Replace ("<", "")).Replace (">", ""))
                printfn "            !!!Recognized node: %s" nodeid
                recgNodes <- recgNodes @ [{NodeId = nodeid}]
            | (false, true, false) -> 
                (* Parsing a Connection *)
                printfn "            ***CONN***"
                logs <- logs @ [{LineNumber = line_index; TokenNumber = token_index; Line = i; Token = j; Log = "Connection recognized"}]
                let nodefromid = (((((new Regex (NodeIdentifierRegex)).Matches (j)).[0].Value).Replace ("<", "")).Replace (">", ""))
                let nodetoid = (((((new Regex (NodeIdentifierRegex)).Matches (j)).[1].Value).Replace ("<", "")).Replace (">", ""))
                let cost = ((((new Regex (WeightValueRegex)).Match (j)).Value).Replace ("\"", ""))
                printfn "            !!!Recognized connection from %s to %s with %s" nodefromid nodetoid cost
                recgConnections <- recgConnections @ [{NodeFromId = nodefromid; NodeToId = nodetoid; ConnectionCost = double cost}]
            | (false, false, true) -> 
                (* Parsing a COmment *)
                printfn "            ***COMM***"
                logs <- logs @ [{LineNumber = line_index; TokenNumber = token_index; Line = i; Token = j; Log = "Comment recognized"}]
            | (_, _, _) -> 
                (* Parsing Unrecognized *)
                printfn "            ***DO NOT KNOW***"
                errs <- errs @ [{LineNumber = line_index; TokenNumber = token_index; Error = ("Unrecognized expression: " + j)}]
                correct <- false
    printfn "--------------------------------------------------------------"
(* Final result *)
let result = {Correctness = correct; Log = logs; Errors = errs}
(* Final resume *)
printfn "------------------------------------------------------------------"
printfn "------------------------------------------------------------------"
printfn "LOG"
for x in result.Log do
    printfn "%s" (PrintParserLogEntry (x))
printfn "------------------------------------------------------------------"
printfn "------------------------------------------------------------------"
printfn "ERRORS"
for x in result.Errors do
    printfn "%s" (PrintFileError (x))
(* Recognized elements *)
printfn "------------------------------------------------------------------"
printfn "------------------------------------------------------------------"
printfn "RECOGNIZED NODES"
for x in recgNodes do
    printfn "RECNODE ==> %s" x.NodeId
printfn "------------------------------------------------------------------"
printfn "------------------------------------------------------------------"
printfn "RECOGNIZED CONNS"
for x in recgConnections do
    printfn "RECNODE ==> from %s to %s cost %f" x.NodeFromId x.NodeToId x.ConnectionCost
printfn "------------------------------------------------------------------"
printfn "------------------------------------------------------------------"
printfn "CORRECT? %b" correct
*)

(* Test for good function *)
printfn ""
printfn "-------------------------"
printfn "Beginning parsing test..."
printfn "-------------------------"
let parseres = ParseNetFile ("C:/Data/VSProjects/RouteSharp/PathFinder/netfile.rs")
printfn "RESULT: %b" parseres.CheckResult.Correctness
printfn "Printing errors..."
for x in parseres.CheckResult.Errors do
    printfn "%s" (PrintFileError (x))
printfn ""
printfn "Printing log..."
for x in parseres.CheckResult.Log do
    printfn "%s" (PrintParserLogEntry (x))
printfn ""
printfn "Printing recognized nodes..."
for x in parseres.Nodes do
    printfn "Node %s" x.NodeId
printfn ""
printfn "Printing recognized connections..."
for x in parseres.Connections do
    printfn "Connection from %s to %s with %f" x.NodeFromId x.NodeToId x.ConnectionCost
printfn ""
printfn "Printing recognized queries..."
for x in parseres.PathQueries do
    printfn "Query requested from node %s to %s" x.PathStartNode x.PathEndNode
(* Analysis *)
printfn ""
printfn "Analyzing..."
let anal1 = AnalyzeConnectionsAfterParse parseres.Nodes parseres.Connections []
for i in anal1 do
    printfn "A connection uses not defined nodes: from=%s to=%s weight=%f" i.NodeFromId i.NodeToId i.ConnectionCost
let anal2 = AnalyzePathQueriesAfterParse parseres.Nodes parseres.PathQueries []
for i in anal2 do
    printfn "A path query uses not defined nodes: from=%s to=%s" i.PathStartNode i.PathEndNode

(* General test *)
let text = "node <NodeA>;  node <NodeB> ; node <NodeC>  ;  node   <NodeD> /* This is a comment */;     node <Node E>   ; node  <Node F > ;    node /* This is a comment */ <Node G>    ;"
let rx = new Regex (NodeDeclarationRegex)
let tokens = text.Split ([|';'|])
for i in tokens do
    printfn "%s %d" i (rx.Matches (i)).Count
for i in rx.Matches (text) do
    printfn "%s" i.Value

(* General test for full declaration *)
printfn ""
let text2 = "node <NodeA> at (1.2 2.3);  node <NodeB>     at (1.2 2.3); node <NodeC>  at (1.2 2.3) ;  node    at (1.2 2.3) <NodeD> /* This is a comment */;     node <Node E>   at (1.2 2.3) ; node  <Node F >     at (1.2 2.3) ;    node /* This is a comment */ <Node G>    ;"
let rxf = new Regex (NodeFullDeclarationRegex)
let tokens2 = text2.Split ([|';'|])
for i in tokens2 do
    printfn "%s %d" i (rxf.Matches (i)).Count
for i in rxf.Matches (text2) do
    printfn "%s" i.Value